# -*- coding: utf-8 -*-
# Author   : ZhangQing
# Time     : 2025-07-15 23:13
# File     : twelve_data_adapter.py
# Project  : dynamic-portfolio-optimizer
# Desc     :
# src/data/adapters/twelve_data_adapter.py
from twelvedata import TDClient
from typing import Dict, List, Any
import pandas as pd
from datetime import datetime
from .base_adapter import BaseDataAdapter, RateLimitDecorator


class TwelveDataAdapter(BaseDataAdapter):
    """Twelve Data适配器"""

    def __init__(self, config):
        super().__init__(config)
        self.client = TDClient(apikey=config.api_key)

    @RateLimitDecorator(calls=8, period=60)
    def get_stock_data(self, symbol: str, start_date: datetime,
                       end_date: datetime, interval: str = '1d') -> pd.DataFrame:
        """获取股票数据"""
        try:
            # 转换时间间隔
            interval_map = {
                '1m': '1min',
                '5m': '5min',
                '15m': '15min',
                '30m': '30min',
                '1h': '1h',
                '1d': '1day'
            }

            td_interval = interval_map.get(interval, '1day')

            # 获取数据
            ts = self.client.time_series(
                symbol=symbol,
                interval=td_interval,
                start_date=start_date.strftime('%Y-%m-%d'),
                end_date=end_date.strftime('%Y-%m-%d'),
                outputsize=5000
            )

            data = ts.as_pandas()

            if data.empty:
                self.logger.warning(f"Twelve Data: 未获取到{symbol}的数据")
                return pd.DataFrame()

            # 重命名列
            data.columns = [col.lower() for col in data.columns]
            data['source'] = 'twelve_data'
            data['symbol'] = symbol

            return self.standardize_data(data)

        except Exception as e:
            self.logger.error(f"Twelve Data获取股票数据失败: {e}")
            return pd.DataFrame()

    def get_options_data(self, symbol: str, expiration_date: datetime) -> pd.DataFrame:
        """获取期权数据"""
        try:
            # Twelve Data支持期权数据
            options = self.client.get_options_chain(
                symbol=symbol,
                expiration_date=expiration_date.strftime('%Y-%m-%d')
            )

            if not options:
                self.logger.warning(f"Twelve Data: 未获取到{symbol}的期权数据")
                return pd.DataFrame()

            options_data = []
            for option in options:
                options_data.append({
                    'symbol': symbol,
                    'contract_symbol': option.get('contract_name', ''),
                    'strike': option.get('strike', 0),
                    'expiration': expiration_date,
                    'type': option.get('type', ''),
                    'bid': option.get('bid', 0),
                    'ask': option.get('ask', 0),
                    'last': option.get('last', 0),
                    'volume': option.get('volume', 0),
                    'open_interest': option.get('open_interest', 0),
                    'source': 'twelve_data'
                })

            return pd.DataFrame(options_data)

        except Exception as e:
            self.logger.error(f"Twelve Data获取期权数据失败: {e}")
            return pd.DataFrame()

    @RateLimitDecorator(calls=8, period=60)
    def get_fundamentals(self, symbol: str) -> Dict[str, Any]:
        """获取基本面数据"""
        try:
            # 获取公司概况
            profile = self.client.get_profile(symbol=symbol)

            if not profile:
                self.logger.warning(f"Twelve Data: 未获取到{symbol}的基本面数据")
                return {}

            # 获取财务数据
            try:
                financials = self.client.get_balance_sheet(symbol=symbol)
                income_statement = self.client.get_income_statement(symbol=symbol)
            except:
                financials = {}
                income_statement = {}

            fundamentals = {
                'symbol': symbol,
                'company_name': profile.get('name', ''),
                'sector': profile.get('sector', ''),
                'industry': profile.get('industry', ''),
                'market_cap': profile.get('market_cap', 0),
                'pe_ratio': profile.get('pe_ratio', 0),
                'pb_ratio': profile.get('pb_ratio', 0),
                'dividend_yield': profile.get('dividend_yield', 0),
                'beta': profile.get('beta', 0),
                'eps': profile.get('eps', 0),
                'revenue': income_statement.get('revenue', 0) if income_statement else 0,
                'description': profile.get('description', ''),
                'employees': profile.get('employees', 0),
                'source': 'twelve_data'
            }

            return fundamentals

        except Exception as e:
            self.logger.error(f"Twelve Data获取基本面数据失败: {e}")
            return {}

    def get_news(self, symbol: str, limit: int = 10) -> List[Dict[str, Any]]:
        """获取新闻数据"""
        try:
            # Twelve Data新闻API
            news_items = self.client.get_news(
                symbol=symbol,
                limit=limit
            )

            processed_news = []
            for item in news_items:
                processed_news.append({
                    'symbol': symbol,
                    'title': item.get('title', ''),
                    'summary': item.get('summary', ''),
                    'url': item.get('url', ''),
                    'published_at': datetime.fromisoformat(item.get('published_at', '')),
                    'source': 'twelve_data',
                    'sentiment': item.get('sentiment', 'neutral')
                })

            return processed_news

        except Exception as e:
            self.logger.error(f"Twelve Data获取新闻数据失败: {e}")
            return []
